home *** CD-ROM | disk | FTP | other *** search
- /* julian.c
- * Part of the Moon application for the NeXT computer.
- * Authors: John Walker of Autodesk
- * Geoffrey S. Knauth (NeXT port)
- * Date: January 4, 1992
- *
- * This code was placed in the public domain by John Walker.
- */
-
- #import "all.h"
-
- /*
- * Convert internal GMT date to Julian day.
- */
- static long jdate(t)
- struct tm *t;
- {
- long c, m, y;
-
- y = t->tm_year + 1900;
- m = t->tm_mon + 1;
- if (m > 2)
- m = m - 3;
- else {
- m = m + 9;
- y--;
- }
- c = y / 100L; /* Compute century */
- y -= 100L * c;
- return t->tm_mday + (c * 146097L) / 4 + (y * 1461L) / 4 +
- (m * 153L + 2) / 5 + 1721119L;
- }
-
- /*
- * Convert internal GMT date and time to astronomical Julian time
- * (i.e. Julian date plus day fraction, expressed as a double).
- */
- double jtime(t)
- struct tm *t;
- {
- return (jdate(t) - 0.5) +
- (t->tm_sec + 60 * (t->tm_min + 60 * t->tm_hour)) / 86400.0;
- }
-
- /*
- * Convert Julian date to year, month, day, which are returned via integer
- * pointers to integers.
- */
- void jyear(td, yy, mm, dd)
- double td;
- int *yy, *mm, *dd;
- {
- double j, d, y, m;
-
- td += 0.5; /* Astronomical to civil */
- j = floor(td);
- j = j - 1721119.0;
- y = floor(((4 * j) - 1) / 146097.0);
- j = (j * 4.0) - (1.0 + (146097.0 * y));
- d = floor(j / 4.0);
- j = floor(((4.0 * d) + 3.0) / 1461.0);
- d = ((4.0 * d) + 3.0) - (1461.0 * j);
- d = floor((d + 4.0) / 4.0);
- m = floor(((5.0 * d) - 3) / 153.0);
- d = (5.0 * d) - (3.0 + (153.0 * m));
- d = floor((d + 5.0) / 5.0);
- y = (100.0 * y) + j;
- if (m < 10.0)
- m = m + 3;
- else {
- m = m - 9;
- y = y + 1;
- }
- *yy = y;
- *mm = m;
- *dd = d;
- }
-
- /*
- * Convert Julian time to hour, minutes, and seconds.
- */
- void jhms(j, h, m, s)
- double j;
- int *h, *m, *s;
- {
- long ij;
-
- j += 0.5; /* Astronomical to civil */
-
- /* I added the rint(), because I noticed that local time was sometimes
- * one second behind the value I expected. --gsk 1/4/92
- */
- ij = rint((j - floor(j)) * 86400.0);
-
- *h = ij / 3600L;
- *m = (ij / 60L) % 60L;
- *s = ij % 60L;
- }
-
- /*********************************************************************
- * The following routines were added to the original Sun moontool code
- * so that the NeXT version could offer the user time travel.
- *********************************************************************
- */
-
- /*
- * Convert {year, month, day} to astronomical Julian date.
- * This is a long, because there is no fraction part (yet).
- */
- static long ymdToJdate(int year, int month, int day)
- {
- long c, m, y;
-
- y = year;
- m = month;
- if (m > 2)
- m = m - 3;
- else {
- m = m + 9;
- y--;
- }
- c = y / 100L; /* Compute century */
- y -= 100L * c;
- return day + (c * 146097L) / 4 + (y * 1461L) / 4 +
- (m * 153L + 2) / 5 + 1721119L;
- }
-
- /*
- * Convert {year, month, day, hour, minute, second} to astronomical Julian
- * date, which will include a fraction, which is why this is a double.
- */
- double ymdhmsToJtime
- (int year, int month, int day,
- int hour, int minute, int second)
- {
- return (ymdToJdate(year, month, day) - 0.5) +
- (second + 60 * (minute + 60 * hour)) / 86400.0;
- }
-